package {
	
	import flash.display.*;
	import flash.events.*;
	import flash.filters.*;
	import flash.geom.*;
	import flash.net.*;
	import flash.text.*;
	
	public class KmcLine extends Sprite {
		//
		public static const LEFT:String = "left";
		public static const CENTER:String = "center";
		public static const RIGHT:String = "right";
		public static const LINE_ONE:String = "line_one";
		public static const LINE_TWO:String = "line_two";
		
		//==================================================
		
		public var kmc:KMC;
		public var xml:XML;
		public var index:int;
		public var type:String;
		public var tx:Number = 0;  //水平偏移量
		public var ty:Number = 0; //垂直位置的偏移量
		public var tw:Number = 0;
		public var th:Number = 0; // 行高
		public var pw:Number = 0; // 父级的宽
		public var ph:Number = 0; // 父级的高
		public var align:String;  //对齐方式  上面为align_one  下面为align_two (右对齐)
		
		
		/**  
		 *  格式
		 *  {start:10, end:50, list:[10, 10, 10, 10]}
		 *  **/
		public var time:Object;  //行的时间  
		public var list:Array;  // 该行的所有单个歌词数组 ['有', '一', '个', '美', '里', '的', '女', '孩']
		public var tips:String;
		public var head:KmcWord;  //开头的tips 面板
		public var dots:Array;    // 3秒信息
		public var sec3:Sprite;  //倒数3秒的信息
		
		public var glow_base:GlowFilter;  //基本文字滤镜
		public var glow_upon:GlowFilter;   // 覆盖文字的滤镜
		public var format_base:TextFormat;
		public var format_upon:TextFormat;
		public var line_base:Sprite;  // 存放单个字符的行
		public var line_upon:Sprite;
		public var mask_base:Sprite;
		public var mask_upon:Sprite;
		
		public var prev:KmcLine;  //前面一行
		public var main:Sprite = new Sprite();
		public var line:Sprite = new Sprite();  // 存放倒数3秒的信息面板、tip面板、歌词主体面板
		public function KmcLine(_xml:XML, _index:int, _kmc:KMC):void {
			kmc = _kmc;
			xml = _xml;
			index = _index;
			type = index % 2 == 0 ? LINE_ONE : LINE_TWO; //得到所在行
			
			prev = kmc.karaoke[index - 1];
			
			pw = kmc.width;
			ph = kmc.height;
			//默认隐藏
			visible = false;
			//初始化
			init();
		}
		
		private function init():void {
			//  xml  <l t="01:45.485,01:50.689,198,261,2553,165,196,197,261,293,1080">有一个美丽的小女孩</l>
			//初始化时间
			time = KMC.parseTime(xml.@t, kmc.offset);
			//初始化格式
			format_base = new TextFormat();
			format_upon = new TextFormat();
			for (var k:String in kmc.format) {
				format_base[k] = format_upon[k] = kmc.format[k];
			}
			format_base.color = kmc.format_color_base;
			format_upon.color = kmc.format_color_upon;
			
			//初始化行内容
			list = parseText(xml);
			
			//生成行
			line_base = lineText(format_base);
			line_upon = lineText(format_upon);
			glow_base = getGlow(kmc.border_color_base, kmc.border);
			glow_upon = getGlow(kmc.border_color_upon, kmc.border);
			line_base.filters = [glow_base];
			line_upon.filters = [glow_upon];
			
			//生成行遮罩
			mask_base = lineMask(line_base.width, line_base.height);
			mask_upon = lineMask(line_base.width, line_base.height);
			mask_upon.width = 0;
			line_base.mask = mask_base;
			line_upon.mask = mask_upon;
			
			//行高，按字体高度确定
			th = line_base.height;
			//倒数3秒信息
			if (!prev || time.start - prev.time.end > kmc.sec3_time) {
				sec3 = newSec3(th);
				line.addChild(sec3);
			}
			//提示信息
			if (tips) {
				head = new KmcWord(tips, format_base);
				head.filters = [glow_base];
				head.tx = line.width;
				line.addChild(head);
			}
			//添加歌词主体
			//歌词主体
			main.addChild(line_base);
			main.addChild(mask_base);
			main.addChild(line_upon);
			main.addChild(mask_upon);
			main.x = line.width;
			line.addChild(main);
			
			//上下位置
			if (type == LINE_ONE) {
				align = kmc.align_one;
				ty = ph * 0.5 - th - kmc.leading * 0.5;
			} else {
				align = kmc.align_two;
				ty = ph * 0.5 + kmc.leading * 0.5;
			}
			//合计行宽
			tw = line.width;
			//左右对齐
			if (align == CENTER) {
				tx = (pw - tw) * 0.5;
			} else if (align == RIGHT) {
				tx = pw - tw - kmc.margin;
			} else {
				tx = kmc.margin;
			}
			//行位置
			line.x = tx;
			line.y = ty;
trace(line.x, line.y, line.width, xml.toString(), pw);
			addChild(line);
		}
		
		//由时间决定是否显示隐藏，以及更新进度
		public function update(t:Number):void {
			//超出时间就延时隐藏
			if (t < time.start) {
				//可能是next，找前一个
				if (prev) {
					if (t >= prev.time.start) {
						if (kmc.line_play) {
							//如果存在正播放的同类型的不显示
							if (kmc.line_play.type == type) {
								hide();
								return;
							}
						}
						if (t > time.start - kmc.preview_time) {
							show();
							showSec3(t);
							return;
						}
					}
				} else {
					//前一个不存在，应该是第一个
					if (t > time.start - kmc.preview_time) {
						show();
						showSec3(t);
						return;
					}
				}
				hide();
				return;
			} else if (t > time.end){
				hide();
				return;
			}
			//
			hideSec3();
			//更新位置
			var pos:Number = 0;
			//当前行内时间增值
			var p:Number = t - time.start;
			if (p > 0) {
				//找到第几个的位置
				var num:int = 0;
				//位置百分比
				var per:Number = 0;
				//循环查找
				var len:int = time.list.length;
				for (var i:int = 0; i < len; i ++) {
					var d:Number = time.list[i];
					if (p <= d) {
						num = i;   
						per = p / d;  //单个字的百分比
						break;
					}
					p -= d;
				}
				//trace(num);
				//显示到位置
				if (num >= 0 && num < line_base.numChildren) {
					var child:KmcWord = line_base.getChildAt(num) as KmcWord;
					if (child) {
						pos = child.tx + child.tw * per;
						trace("move ", pos);
					}
				}
			}
			
			showPos(pos);
			if (kmc.line_play == null) {
				kmc.line_play = this;
			}
		}
		
		
		/**
		 *    显示百分比, 将mask移动到具体的位置
		 *  **/
		public function showPos(pos:Number):void {

			mask_base.x = pos;
			mask_base.width = tw - pos;
			mask_upon.width = pos;
			visible = true;
		}
		
		public function show():void {
			showPos(0);
		}
		
		public function hide():void {
			visible = false;
		}
		
		
		private function showSec3(t:Number):void {
			if (!sec3) {
				return;
			}
			sec3.visible = true;
			for each(var dot:Shape in dots) {
				dot.alpha = 1;
			}
			var i:int = Math.floor((time.start - t) * 0.001);
			if (i == 2) {
				dots[0].alpha = 0.1;
			} else if (i == 1) {
				dots[0].alpha = 0.1;
				dots[1].alpha = 0.1;
			} else if (i == 0) {
				dots[0].alpha = 0.1;
				dots[1].alpha = 0.1;
				dots[2].alpha = 0.1;
			}
		}
		private function hideSec3():void {
			if (!sec3) {
				return;
			}
			sec3.visible = false;
		}
		//====================================================================
			// str 由xml变成字符串  因为该xml为简单类型
		private function parseText(str:String):Array {
			str = KMC.trim(str);
			//解析提示  提示只有该句歌词最前面才有
			var a:Array = str.match(/^\(([^\)]+)\)/);
			if (a is Array) {
				tips = a[0];
				str = str.substr(tips.length);
			}
			//解析行内字段
			var arr:Array = [];
			var reg:RegExp = /^\[([^\]]+)\]/;
			while (str.length) {
				var l:int = 1;
				var s:String;
				var m:Array = str.match(reg);
				if (m is Array) {
					l = m[0].length;
					s = m[1];
				} else {
					s = str.charAt(0);
				}
				arr.push(s);
				str = str.substr(l);
			}
			return arr;
		}
		
		//====================================================================
		private function getGlow(color:uint, obj:Object):GlowFilter {
			var quality:Number = BitmapFilterQuality.MEDIUM;
			return new GlowFilter(color, obj.alpha, obj.blur, obj.blur, obj.strength, quality, false, false);
		}
		
		
		private function lineText(format:TextFormat):Sprite {
			var sp:Sprite = new Sprite();
			var len:int = list.length;
			var spx:int = 0;
			for (var i:int = 0; i < len; i ++) {
				var t:KmcWord = new KmcWord(list[i], format);
				t.tx = spx;
				sp.addChild(t);
				spx += t.tw;
			}
			return sp;
		}
		
		private function newText(str:String, format:TextFormat):TextField {
			var t:TextField = new TextField();
			t.autoSize = TextFieldAutoSize.LEFT;
			t.multiline = false;
			t.selectable = false;
			t.htmlText = str;
			t.setTextFormat(format);
			return t;
		}
		
		private function newSec3(tr:Number):Sprite {
			var sp:Sprite = new Sprite();
			dots = [];
			for (var i:int = 0; i < 3; i ++) {
				var o:Shape = newO(tr);
				o.x = tr * i * 0.6;
				sp.addChild(o);
				dots.push(o);
			}
			return sp;
		}
		
		private function newO(tr:Number):Shape {
			var o:Shape = new Shape();
			o.graphics.lineStyle(kmc.border.thickness, kmc.border_color_base, kmc.border.alpha);
			o.graphics.beginFill(kmc.format_color_base, 1);
			o.graphics.drawCircle(0, tr * 0.5, tr * 0.2);
			o.graphics.endFill();
			return o;
		}
		
		private function lineMask(w:Number, h:Number):Sprite {
			var s:Sprite = new Sprite();
			s.graphics.beginFill(0xffffff, 1);
			s.graphics.drawRect(0,0,w,h);
			s.graphics.endFill();
			return s;
		}
		
		
	}
	
}